srcdir = @srcdir@
builddir = @builddir@
VPATH = @srcdir@

prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
mandir = @mandir@
datarootdir = @datarootdir@
sysconfdir = @sysconfdir@
installcmd = @INSTALL@

BASH = @BASH@
CC = @CC@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXFLAGS = @CXXFLAGS@
EXEEXT = @EXEEXT@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@

all_cflags = $(CFLAGS)
all_cxxflags = $(CXXFLAGS)
all_cppflags = @DEFS@ -DSYSCONFDIR=$(sysconfdir) -I. -I$(srcdir)/src -I$(builddir)/unittest $(CPPFLAGS)
extra_libs = @extra_libs@

v_at_0 = yes
v_at_ = $(v_at_0)
quiet := $(v_at_$(V))
Q=$(if $(quiet),@)

non_third_party_sources = \
    src/ArgsInfo.cpp \
    src/AtomicFile.cpp \
    src/CacheEntryReader.cpp \
    src/CacheEntryWriter.cpp \
    src/CacheFile.cpp \
    src/Compression.cpp \
    src/Compressor.cpp \
    src/Config.cpp \
    src/Context.cpp \
    src/Counters.cpp \
    src/Decompressor.cpp \
    src/Lockfile.cpp \
    src/NullCompressor.cpp \
    src/NullDecompressor.cpp \
    src/ProgressBar.cpp \
    src/Stat.cpp \
    src/Util.cpp \
    src/ZstdCompressor.cpp \
    src/ZstdDecompressor.cpp \
    src/args.cpp \
    src/ccache.cpp \
    src/cleanup.cpp \
    src/compopt.cpp \
    src/compress.cpp \
    src/execute.cpp \
    src/exitfn.cpp \
    src/hash.cpp \
    src/hashutil.cpp \
    src/language.cpp \
    src/legacy_util.cpp \
    src/logging.cpp \
    src/manifest.cpp \
    src/result.cpp \
    src/stats.cpp \
    src/win32compat.cpp
generated_sources = \
    src/version.cpp
third_party_sources = \
    src/third_party/format.cpp \
    src/third_party/getopt_long.c \
    src/third_party/xxhash.c
extra_sources = @extra_sources@
base_sources = $(non_third_party_sources) $(generated_sources) $(third_party_sources) $(extra_sources)
base_objs = $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(base_sources)))

non_third_party_objs = $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(non_third_party_sources)))

ccache_sources = src/main.cpp $(base_sources)
ccache_objs = $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(ccache_sources)))

test_suites += unittest/test_AtomicFile.cpp
test_suites += unittest/test_Checksum.cpp
test_suites += unittest/test_Compression.cpp
test_suites += unittest/test_Config.cpp
test_suites += unittest/test_FormatNonstdStringView.cpp
test_suites += unittest/test_Lockfile.cpp
test_suites += unittest/test_NullCompression.cpp
test_suites += unittest/test_ScopeGuard.cpp
test_suites += unittest/test_Stat.cpp
test_suites += unittest/test_Util.cpp
test_suites += unittest/test_ZstdCompression.cpp
test_suites += unittest/test_args.cpp
test_suites += unittest/test_argument_processing.cpp
test_suites += unittest/test_compopt.cpp
test_suites += unittest/test_hash.cpp
test_suites += unittest/test_hashutil.cpp
test_suites += unittest/test_legacy_util.cpp

test_sources += unittest/catch2_tests.cpp
test_sources += unittest/framework.cpp
test_sources += unittest/main.cpp
test_sources += unittest/util.cpp
test_sources += $(test_suites)
test_objs = $(test_sources:.cpp=.o)

all_sources = $(ccache_sources) $(test_sources)
all_objs = $(ccache_objs) $(test_objs)

files_to_clean = \
    $(all_objs) \
    ccache$(EXEEXT) \
    src/*~ \
    testdir.* \
    unittest/run$(EXEEXT) \
    *~

files_to_distclean = Makefile config.h config.log config.status

.PHONY: all
all: ccache$(EXEEXT)

ccache$(EXEEXT): $(ccache_objs) $(extra_libs)
	$(if $(quiet),@echo "  LD       $@")
	$(Q)$(CXX) -o $@ $(ccache_objs) $(LDFLAGS) $(extra_libs) $(LIBS)

ccache.1: doc/ccache.1
	$(if $(quiet),@echo "  CP       $@")
	$(Q)cp $< $@

.PHONY: install
install: ccache$(EXEEXT) @disable_man@ccache.1
	$(if $(quiet),@echo "  INSTALL  ccache$(EXEEXT)")
	$(Q)$(installcmd) -d $(DESTDIR)$(bindir)
	$(Q)$(installcmd) -m 755 ccache$(EXEEXT) $(DESTDIR)$(bindir)
@disable_man@	$(if $(quiet),@echo "  INSTALL  ccache.1")
@disable_man@	$(Q)$(installcmd) -d $(DESTDIR)$(mandir)/man1
@disable_man@	$(Q)-$(installcmd) -m 644 ccache.1 $(DESTDIR)$(mandir)/man1/

.PHONY: clean
clean:
	rm -rf $(files_to_clean)
	[ ! -f src/third_party/zstd/Makefile ] || $(MAKE) -C src/third_party/zstd/lib clean
	[ ! -f src/third_party/libb2/Makefile ] || $(MAKE) -C src/third_party/libb2 clean

$(non_third_party_objs) $(test_objs): CFLAGS += @extra_warnings@
$(non_third_party_objs) $(test_objs): CXXFLAGS += @extra_warnings@

libzstd_options = \
    ZSTD_LEGACY_SUPPORT=0 \
    ZSTD_LIB_DEPRECATED=0 \
    ZSTD_LIB_DICTBUILDER=0

src/third_party/zstd/lib/libzstd.a:
	$(MAKE) -C src/third_party/zstd/lib libzstd.a $(libzstd_options) CC="$(CC)"

libb2_options = \
    --disable-shared \
    --enable-static

@disable_cross@# cross compilation
@disable_cross@libb2_options += \
@disable_cross@    --build=@build_alias@ \
@disable_cross@    --host=@host_alias@ \
@disable_cross@    --target=@target_alias@ \
@disable_cross@    --disable-openmp \
@disable_cross@    --disable-fat \
@disable_cross@    --disable-native

src/third_party/libb2/src/.libs/libb2.a:
	cd src/third_party/libb2 && ./configure ${libb2_options} CC="$(CC)"
	$(MAKE) -C src/third_party/libb2 CC="$(CC)" \
@disable_cross@	CFLAGS="$(CFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)"

.PHONY: performance
performance: ccache$(EXEEXT)
	$(srcdir)/misc/performance --ccache ccache$(EXEEXT) $(CXX) $(all_cppflags) $(all_cxxflags) $(srcdir)/src/ccache.cpp

.PHONY: test
test: ccache$(EXEEXT) unittest/run$(EXEEXT)
	$(if $(quiet),@echo "  TEST     unittest/run$(EXEEXT)")
	$(Q)unittest/run$(EXEEXT)
	$(if $(quiet),@echo "  TEST     $(srcdir)/test/run")
	$(Q)CC='$(CC)' $(BASH) $(srcdir)/test/run

.PHONY: unittest
unittest: unittest/run$(EXEEXT)
	$(if $(quiet),@echo "  TEST     $@")
	$(Q)unittest/run$(EXEEXT)

unittest/run$(EXEEXT): $(base_objs) $(test_objs) $(extra_libs)
	$(if $(quiet),@echo "  LD       $@")
	$(Q)$(CXX) -o $@ $(base_objs) $(test_objs) $(LDFLAGS) $(extra_libs) $(LIBS)

.PHONY: check
check: test

.PHONY: distclean
distclean: clean
	rm -rf $(files_to_distclean)

.PHONY: installcheck
installcheck: ccache$(EXEEXT) unittest/run$(EXEEXT)
	unittest/run$(EXEEXT)
	CCACHE=$(bindir)/ccache CC='$(CC)' $(BASH) $(srcdir)/test/run

.c.o:
	$(if $(quiet),@echo "  CC       $@")
	$(Q)$(CC) $(all_cppflags) $(all_cflags) -c -o $@ $<

.cpp.o:
	$(if $(quiet),@echo "  CXX      $@")
	$(Q)$(CXX) $(all_cppflags) $(all_cxxflags) -c -o $@ $<

@include_dev_mk@
